package com.fasterxml.jackson.databind.node;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.util.Objects;

/**
 * 添加EnumNode类，处理枚举
 */
public class EnumNode extends ValueNode {
    private final Enum<?> value;

    private EnumNode(Enum<?> value) {
        this.value = Objects.requireNonNull(value);
    }

    public static EnumNode valueOf(Enum<?> value) {
        return new EnumNode(value);
    }

    public Enum<?> getEnum() {
        return value;
    }

    @Override
    public String asText() {
        return value.name();
    }

    @Override
    public JsonToken asToken() {
        return JsonToken.VALUE_ENUM;
    }

    @Override
    public JsonNodeType getNodeType() {
        return JsonNodeType.ENUM;
    }

    @Override
    public void serialize(JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (value instanceof JsonSerializable) {
            ((JsonSerializable) value).serialize(gen, provider);
        } else {
            // 25-May-2018, tatu: [databind#1991] do not call via generator but through context;
            //    this to preserve contextual information
            provider.defaultSerializeValue(value, gen);
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T extends JsonNode> T deepCopy() {
        return (T) new EnumNode(value);
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (o == null || getClass() != o.getClass()) return false;
        EnumNode that = (EnumNode) o;
        return value == that.value;
    }

    @Override
    public int hashCode() {
        return value.hashCode();
    }

    @Override
    public String toString() {
        return value.name();
    }

    @Override
    public JsonParser.NumberType numberType() {
        return JsonParser.NumberType.INT;
    }

    @Override
    public boolean canConvertToInt() {
        return true;
    }

    @Override
    public boolean canConvertToLong() {
        return true;
    }

    @Override
    public int asInt() {
        return value.ordinal();
    }

    @Override
    public int asInt(int defaultValue) {
        return value.ordinal();
    }

    @Override
    public long asLong() {
        return value.ordinal();
    }

    @Override
    public long asLong(long defaultValue) {
        return value.ordinal();
    }

    @Override
    public double asDouble() {
        return value.ordinal();
    }

    @Override
    public double asDouble(double defaultValue) {
        return value.ordinal();
    }
}